package org.streets.eis.component.tabs;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.apache.wicket.AbortException;
import org.apache.wicket.authorization.AuthorizationException;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.markup.MarkupException;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;

public class Tab extends AbstractTab {
	
	private static final long serialVersionUID = 1L;

	private String id;
	
	private String tabTitle;

	private boolean isVisibled;
	
	protected Class<? extends Panel> panelClass;

	public Tab(String id,String tabTitle,Class<? extends Panel> panelClass){
		this(id,tabTitle,panelClass,true);
	}
	
	public Tab(String id,String tabTitle,Class<? extends Panel> panelClass,boolean isVisibled){
		super(new Model<String>(tabTitle));
		this.id = id;
		this.tabTitle = tabTitle;
		this.panelClass = panelClass;
		this.isVisibled = isVisibled;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getTabTitle() {
		return tabTitle;
	}

	public void setTabTitle(String tabTitle) {
		this.tabTitle = tabTitle;
	}
	
	@Override
	public boolean isVisible() {
		return isVisibled;
	}

	public boolean isVisibled() {
		return isVisibled;
	}	
	
	public void setVisibled(boolean isVisibled) {
		this.isVisibled = isVisibled;
	}

	protected String createDescription(Constructor<? extends Panel> constructor,String panelId){
		return "Can't instantiate panel using constructor " + constructor + " and argument " + panelId;
	}
	
	@Override
	public Panel getPanel(String panelId) {
		Constructor<? extends Panel> constructor =null;
		try{
			constructor = panelClass.getConstructor(getPanelConstructorParameterTypes());
		}catch (NoSuchMethodException e){
		}
		
		if (constructor!=null){
			try{
				return constructor.newInstance(getPanelConstructorParameterValues(panelId));
			} catch (IllegalArgumentException e) {
				throw new RuntimeException(createDescription(constructor, panelId), e);
			} catch (InstantiationException e) {
				throw new RuntimeException(createDescription(constructor, panelId), e);
			} catch (IllegalAccessException e) {
				throw new RuntimeException(createDescription(constructor, panelId), e);
			} catch (InvocationTargetException e) {
				if (e.getTargetException() instanceof AbortException ||
						e.getTargetException() instanceof AuthorizationException ||
						e.getTargetException() instanceof MarkupException)
					{
						throw (RuntimeException)e.getTargetException();
					}
					throw new RuntimeException(createDescription(constructor, panelId), e);
			}
		}
		
		throw new RuntimeException("Unable to create panel from " + panelClass +
		". Class does neither have a constructor with String nor a default constructor");		
	}
	
	protected Class<?>[] getPanelConstructorParameterTypes(){
		return new Class<?>[] {String.class};
	}
	
	protected Object[] getPanelConstructorParameterValues(String panelId){
		return new Object[] {panelId};
	}
}
